package Poker;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Vector;

public class Table {
	List<Account> accounts = new ArrayList<Account>();
	List<Account> accounts_waiting = new ArrayList<Account>();
	Deck deck; //= new Deck();
	private int entry = 0; //Wpisowe 
	private int current_entry = 0;
	private int max_bet = 0;
	
	public Table(int entry)
	{
		this.entry = entry;
		max_bet = entry;
	}
	
	public void StartRound()
	{
		SetAcountsStartChips(100);
		
		while(accounts.size() > 0)
		{
			deck = new Deck();
			Entry();
			Deal();
			Bet();
			Query();
			Bet();
			
			List<Account> winners = null;
			if(!accounts.isEmpty())
			{
				winners = GetWinner();
				if(winners.size() > 1) //Wszyscy trac� co obstawili
				{
					for(Account a: accounts)
					{
						a.SetChips(a.GetChips() - a.GetChipsInGame());
						a.SetChipsInGame(0);
					}
				}
				else
				{
					winners.get(0).SetChips(winners.get(0).GetChips() + current_entry);
					winners.get(0).SetChipsInGame(0);
					for(Account a: accounts)
					{
						if(a != winners.get(0))
						{
							winners.get(0).SetChips(winners.get(0).GetChips() + a.GetChipsInGame());
							a.SetChips(a.GetChips() - a.GetChipsInGame());
							a.SetChipsInGame(0);
						}
					}
				}
				
				current_entry = entry;
				max_bet = entry;
				
				System.out.println("Wygrani: ");
				for(Account a: winners)
				{
					System.out.print("Gracz: " + a.GetName() + " �etony: ");
					System.out.println(a.GetChips());
					
				}
				System.out.println("Z kartami: ");
				for (Card x : winners.get(0).GetCards())
				{
					System.out.println(x.toString());
				}
				
				//Przywr�cenie graczy kt�rzy zrezygnowali w poprzedniej partii (przepisanie ich z oczekuj�cych do tych kt�rzy s� w grze)
				for(int i = 0; i < accounts_waiting.size(); ++i)
				{
					accounts.add(accounts_waiting.remove(i));
					i--;
				}
				
			}
			else
			{
				System.out.println("Wszyscy opu�cili gr�.");
			}
		}
	}
	
	public void SetAcountsStartChips(int chips)
	{
		for(Account a: accounts)
		{
			a.SetChips(chips);
		}
	}
	
	public void Deal()
	{
		for(Account a: accounts)
		{
			Vector<Card> player_cards = new Vector<Card>();
			for(int i = 0; i < 5; ++i)
			{
				player_cards.add(deck.GetCard());
			}
			
			a.SetCards(player_cards);
		}
	}
	
	public void Entry()
	{
		for(int i = 0; i < accounts.size(); i++)
		{
			if(accounts.get(i).GetChips() >= entry)
			{
				if(!accounts.get(i).Entry(entry))//Je�eli gracz zwr�ci� -1 to nie chce gra�
				{
					accounts_waiting.add(accounts.remove(i));
					i--;
				}
				else
				{
					current_entry += entry;
				}
			}
			else
			{
				accounts.get(i).Message("Masz za ma�o �eton�w �eby wej�� do gry.");
				accounts_waiting.add(accounts.remove(i));
				i--;
			}
		}
	}
	
	public void Bet()
	{
		boolean is_bet = true;
		while(is_bet)
		{
			is_bet = false;
			
			for(int i = 0; i < accounts.size(); i++)
			{
				int b = accounts.get(i).Bet(max_bet);
				
				if(b == -1)
				{
					accounts_waiting.add(accounts.remove(i));
					i--;
				}
				else if(b > max_bet)
				{
					is_bet = true;
					max_bet = b;
				}
				else if(b == max_bet)
				{
					max_bet = b;
				}
			}
		}
	}
	
	public void Query()
	{
		for(Account a: accounts)
		{
			Vector<Integer> query = a.Query();
			if(!query.isEmpty())		
			{
				Collections.sort(query);
				Vector<Card> cards = a.GetCards();
				int no_cards = query.size();
				for (int i =  no_cards-1 ; i >= 0; i-- )
				{
					cards.remove((query.get(i)-1));
				}
				for (int i =  no_cards; i > 0; --i )
				{
					cards.add(deck.GetCard());
				}
					a.SetCards(cards);		
					a.PrintChangeCard();
			}
			
		}
	}
	
	public List<Account> GetWinner()
	{
		List<Account> winners = new ArrayList<Account>(accounts);
		
		Account max = winners.get(0);
		for(Account a: winners)
		{
			if(a.GetScore()[0] >= max.GetScore()[0])
			{
				max = a;
			}
		}
		
		for(int i = 0; i < winners.size(); ++i)
		{
			if(winners.get(i).GetScore()[0] != max.GetScore()[0])
			{
				
				winners.remove(i);
				--i;
			}
		}
		
		max = winners.get(0);
		
		for(Account a: winners)
		{
			if(a.GetScore()[1] >= max.GetScore()[1])
			{
				max = a;
			}
		}
		
		for(int i = 0; i < winners.size(); ++i)
		{
			if(winners.get(i).GetScore()[1] != max.GetScore()[1])
			{
				winners.remove(i);
				--i;
			}
		}
		
		return winners;
	}
	
	public void AddPlayer(String player_name, String player_type)
	{	
		switch(player_type.charAt(0)) {
		case '1':
			accounts.add(new Account(player_name, "bot"));
			break;
		case '0':
			accounts.add(new Account(player_name, "human"));
			break;
		}
	}
	
	public List<Account> GetAccounts()
	{
		return accounts;
	}
	
	public List<Account> GetWaitingAccounts()
	{
		return accounts_waiting;
	}
}
